package com.ext.aic.excutor;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Rect;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

import com.ext.aic.AICApplication;
import com.ext.aic.beans.OCRProcessMeta;
import com.ext.aic.events.OnRecognizeListener;
import com.eyinfo.storage.files.FileUtils;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.mlkit.vision.common.InputImage;
import com.google.mlkit.vision.text.Text;
import com.google.mlkit.vision.text.TextRecognizer;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.IOException;

public class ProcessRunnable implements Runnable {
    private OCRProcessMeta meta;
    private int position;
    private String fileId;
    private String extension;
    private OnRecognizeListener recognitionListener;

    public ProcessRunnable(OCRProcessMeta meta, int position, OnRecognizeListener recognitionListener) {
        this.meta = meta;
        this.position = position;
        this.recognitionListener = recognitionListener;
    }

    private InputImage getInputImage(OCRProcessMeta meta) {
        InputImage image = null;
        Context applicationContext = AICApplication.getInstance().getApplicationContext();
        if (meta.getImageResId() != 0) {
            Resources resources = applicationContext.getResources();
            Bitmap bitmap = BitmapFactory.decodeResource(resources, meta.getImageResId());
            image = InputImage.fromBitmap(bitmap, 0);
        } else if (!TextUtils.isEmpty(meta.getPath())) {
            File file = new File(meta.getPath());
            if (file.exists()) {
                try {
                    Uri uri = Uri.fromFile(file);
                    image = InputImage.fromFilePath(applicationContext, uri);
                } catch (IOException e) {
                    Thread.currentThread().interrupt();
                    e.printStackTrace();
                }
            }
        }
        return image;
    }

    @Override
    public void run() {
        try {
            String path = meta.getPath();
            if (!TextUtils.isEmpty(path)) {
                fileId = FileUtils.getBaseName(path);
                extension = FileUtils.getExtension(path);
            }
            InputImage inputImage = getInputImage(meta);
            if (inputImage == null) {
                if (recognitionListener != null) {
                    recognitionListener.onRecognizeCall("", position, fileId, extension);
                }
                return;
            }
            TextRecognizer recognizer = AICApplication.getInstance().getTextRecognizer();
            recognizer.process(inputImage)
                    .addOnSuccessListener(result -> {
                        try {
                            JSONArray textsArray = new JSONArray();
                            for (Text.TextBlock block : result.getTextBlocks()) {
                                JSONObject blockJson = buildTextBlockJson(block);
                                textsArray.put(blockJson);
                            }
                            JSONObject resultJson = new JSONObject();
                            resultJson.put("texts", textsArray);
                            String jsonOutput = resultJson.toString();
                            if (recognitionListener != null) {
                                recognitionListener.onRecognizeCall(jsonOutput, position, fileId, extension);
                            }
                            deleteFile(meta);
                        } catch (JSONException e) {
                            if (recognitionListener != null) {
                                recognitionListener.onRecognizeCall("", position, fileId, extension);
                            }
                            deleteFile(meta);
                        }
                    })
                    .addOnFailureListener(e -> {
                        if (recognitionListener != null) {
                            recognitionListener.onRecognizeCall("", position, fileId, extension);
                        }
                        deleteFile(meta);
                    })
                    .addOnCompleteListener(new OnCompleteListener() {
                        @Override
                        public void onComplete(Task task) {
                            if (recognitionListener != null) {
                                recognitionListener.onRecognizeCall("finish", position, fileId, extension);
                            }
                        }
                    });
        } catch (Exception e) {
            if (recognitionListener != null) {
                recognitionListener.onRecognizeCall("", position, fileId, extension);
            }
            deleteFile(meta);
        }
    }

    private void deleteFile(OCRProcessMeta meta) {
        if (TextUtils.isEmpty(meta.getPath())) {
            return;
        }
        File file = new File(meta.getPath());
        boolean delete = file.delete();
        if (delete) {
            Log.d("deleteFile", meta.getPath());
        }
    }

    private JSONObject buildTextBlockJson(Text.TextBlock block) throws JSONException {
        JSONObject blockJson = new JSONObject();
        blockJson.put("text", block.getText());

        Rect bounds = block.getBoundingBox();
        if (bounds != null) {
            JSONObject boundsJson = new JSONObject();
            boundsJson.put("left", bounds.left);
            boundsJson.put("top", bounds.top);
            boundsJson.put("right", bounds.right);
            boundsJson.put("bottom", bounds.bottom);
            blockJson.put("boundingBox", boundsJson);
        }

        // 添加语言信息
        String language = block.getRecognizedLanguage();
        if (language != null) {
            blockJson.put("language", language);
        }

        // 处理Lines和Elements
        JSONArray linesArray = new JSONArray();
        for (Text.Line line : block.getLines()) {
            JSONObject lineJson = buildLineJson(line);
            linesArray.put(lineJson);
        }
        blockJson.put("lines", linesArray);

        return blockJson;
    }

    private JSONObject buildLineJson(Text.Line line) throws JSONException {
        JSONObject lineJson = new JSONObject();
        lineJson.put("text", line.getText());

        Rect lineBounds = line.getBoundingBox();
        if (lineBounds != null) {
            JSONObject lineBoundsJson = new JSONObject();
            lineBoundsJson.put("left", lineBounds.left);
            lineBoundsJson.put("top", lineBounds.top);
            lineBoundsJson.put("right", lineBounds.right);
            lineBoundsJson.put("bottom", lineBounds.bottom);
            lineJson.put("boundingBox", lineBoundsJson);
        }

        // 处理Elements
        JSONArray elementsArray = new JSONArray();
        for (Text.Element element : line.getElements()) {
            JSONObject elementJson = buildElementJson(element);
            elementsArray.put(elementJson);
        }
        lineJson.put("elements", elementsArray);

        return lineJson;
    }

    private JSONObject buildElementJson(Text.Element element) throws JSONException {
        JSONObject elementJson = new JSONObject();
        elementJson.put("text", element.getText());

        Rect elementBounds = element.getBoundingBox();
        if (elementBounds != null) {
            JSONObject elementBoundsJson = new JSONObject();
            elementBoundsJson.put("left", elementBounds.left);
            elementBoundsJson.put("top", elementBounds.top);
            elementBoundsJson.put("right", elementBounds.right);
            elementBoundsJson.put("bottom", elementBounds.bottom);
            elementJson.put("boundingBox", elementBoundsJson);
        }

        return elementJson;
    }
}
